<%
Class FastAsp_Cache
    Private m_Type       '缓存类型
    Private m_Path       '缓存路径
    Private m_Time       '缓存时间
    Private m_Cache      '内存缓存对象
    Private m_Prefix     '缓存前缀
    Private m_Debug      '调试模式
    
    Private Sub Class_Initialize()
        m_Type = GetConfig("CacheType")
        If m_Type = "" Then m_Type = "file"
        m_Path = GetConfig("CachePath")
        If m_Path = "" Then m_Path = "/runtime/cache"
        m_Time = GetConfig("CacheTime")
        If m_Time = "" Then m_Time = 3600
        m_Prefix = GetConfig("CachePrefix")
        If m_Prefix = "" Then m_Prefix = "fast_"
        m_Debug = GetConfig("DebugMode")
        
        '初始化内存缓存
        If m_Type = "memory" Then
            Set m_Cache = Server.CreateObject("Scripting.Dictionary")
        End If
    End Sub
    
    '设置缓存
    Public Function [Set](byval key, byval value, byval expire)
        If expire = "" Then expire = m_Time
        key = m_Prefix & key '添加前缀
        
        If m_Debug Then
            Fast.Debug.Add "Cache.Set", "key=" & key & ", expire=" & expire & "s"
        End If
        
        Select Case m_Type
            Case "file"   SetFileCache key, value, expire
            Case "memory" SetMemoryCache key, value, expire
        End Select
        Set [Set] = Me
    End Function
    
    '获取缓存
    Public Function [Get](byval key)
        key = m_Prefix & key '添加前缀
        
        If m_Debug Then
            Fast.Debug.Add "Cache.Get", "key=" & key
        End If
        
        Select Case m_Type
            Case "file"   [Get] = GetFileCache(key)
            Case "memory" [Get] = GetMemoryCache(key)
        End Select
    End Function
    
    '删除缓存
    Public Function Delete(byval key)
        key = m_Prefix & key '添加前缀
        
        If m_Debug Then
            Fast.Debug.Add "Cache.Delete", "key=" & key
        End If
        
        Select Case m_Type
            Case "file"   DeleteFileCache key
            Case "memory" DeleteMemoryCache key
        End Select
        Set Delete = Me
    End Function
    
    '清空缓存
    Public Function Clear()
        If m_Debug Then
            Fast.Debug.Add "Cache.Clear", "type=" & m_Type
        End If
        
        Select Case m_Type
            Case "file"   ClearFileCache
            Case "memory" ClearMemoryCache
        End Select
        Set Clear = Me
    End Function
    
    '检查缓存是否存在
    Public Function Exists(byval key)
        key = m_Prefix & key '添加前缀
        Select Case m_Type
            Case "file"   Exists = FSO.FileExists(GetCacheFile(key))
            Case "memory" Exists = m_Cache.Exists(key)
        End Select
    End Function
    
    '获取缓存剩余时间(秒)
    Public Function TTL(byval key)
        key = m_Prefix & key '添加前缀
        Dim data, expire
        
        Select Case m_Type
            Case "file"
                data = GetFileCacheData(key)
                If Not data Is Nothing Then expire = data("expire")
            Case "memory"
                If m_Cache.Exists(key) Then
                    Set data = m_Cache(key)
                    expire = data("expire")
                End If
        End Select
        
        If IsDate(expire) Then
            TTL = DateDiff("s", Now(), CDate(expire))
            If TTL < 0 Then TTL = -1
        Else
            TTL = -1
        End If
    End Function
    
    '设置文件缓存
    Private Sub SetFileCache(byval key, byval value, byval expire)
        '创建缓存目录
        CreateFolder Server.MapPath(m_Path)
        
        '缓存数据
        Dim data : Set data = Server.CreateObject("Scripting.Dictionary")
        data.Add "data", value
        data.Add "expire", Now() + (expire / 86400) '转换为天数
        data.Add "created", Now()
        
        '保存缓存文件
        Dim file : file = GetCacheFile(key)
        SaveFile file, JSON.Encode(data)
    End Sub
    
    '获取文件缓存
    Private Function GetFileCache(byval key)
        Dim data : Set data = GetFileCacheData(key)
        If Not data Is Nothing Then GetFileCache = data("data")
    End Function
    
    '获取文件缓存数据
    Private Function GetFileCacheData(byval key)
        Dim file : file = GetCacheFile(key)
        If Not FSO.FileExists(file) Then Exit Function
        
        '读取缓存数据
        Dim content : content = LoadFile(file)
        If content = "" Then Exit Function
        
        '解析缓存数据
        Dim data : Set data = JSON.Decode(content)
        If data Is Nothing Then Exit Function
        
        '检查是否过期
        If IsDate(data("expire")) Then
            If Now() > CDate(data("expire")) Then
                FSO.DeleteFile file
                Exit Function
            End If
        End If
        
        Set GetFileCacheData = data
    End Function
    
    '删除文件缓存
    Private Sub DeleteFileCache(byval key)
        Dim file : file = GetCacheFile(key)
        If FSO.FileExists(file) Then FSO.DeleteFile file
    End Sub
    
    '清空文件缓存
    Private Sub ClearFileCache()
        Dim folder : folder = Server.MapPath(m_Path)
        If FSO.FolderExists(folder) Then FSO.DeleteFolder folder
    End Sub
    
    '设置内存缓存
    Private Sub SetMemoryCache(byval key, byval value, byval expire)
        Dim data : Set data = Server.CreateObject("Scripting.Dictionary")
        data.Add "data", value
        data.Add "expire", Now() + (expire / 86400)
        data.Add "created", Now()
        m_Cache(key) = data
    End Sub
    
    '获取内存缓存
    Private Function GetMemoryCache(byval key)
        If Not m_Cache.Exists(key) Then Exit Function
        
        Dim data : Set data = m_Cache(key)
        If IsDate(data("expire")) Then
            If Now() > CDate(data("expire")) Then
                m_Cache.Remove key
                Exit Function
            End If
        End If
        
        GetMemoryCache = data("data")
    End Function
    
    '删除内存缓存
    Private Sub DeleteMemoryCache(byval key)
        If m_Cache.Exists(key) Then m_Cache.Remove key
    End Sub
    
    '清空内存缓存
    Private Sub ClearMemoryCache()
        m_Cache.RemoveAll
    End Sub
    
    '获取缓存文件路径
    Private Function GetCacheFile(byval key)
        GetCacheFile = Server.MapPath(m_Path & "/" & MD5(key) & ".cache")
    End Function
    
    '保存文件
    Private Sub SaveFile(byval file, byval content)
        Dim stream : Set stream = CreateObject("ADODB.Stream")
        stream.Type = 2 'adTypeText
        stream.Charset = "utf-8"
        stream.Open
        stream.WriteText content
        stream.SaveToFile file, 2
        stream.Close
        Set stream = Nothing
    End Sub
    
    '读取文件
    Private Function LoadFile(byval file)
        Dim stream : Set stream = CreateObject("ADODB.Stream")
        stream.Type = 2 'adTypeText
        stream.Charset = "utf-8"
        stream.Open
        stream.LoadFromFile file
        LoadFile = stream.ReadText
        stream.Close
        Set stream = Nothing
    End Function
    
    '创建文件夹
    Private Sub CreateFolder(byval path)
        Dim fso : Set fso = Server.CreateObject("Scripting.FileSystemObject")
        If Not fso.FolderExists(path) Then
            CreateFolder fso.GetParentFolderName(path)
            fso.CreateFolder path
        End If
    End Sub
    
    Private Sub Class_Terminate()
        If Not m_Cache Is Nothing Then Set m_Cache = Nothing
    End Sub
End Class
%> 